﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpModelInterface.h"
#include "IElement.h"
#include "ElementCreationOptions.h"

namespace gcmp {
    class IGraphicsElementShape;
    class Matrix4d;
    class MoveContext;
    class IType;
    class UniIdentity;
    class Vector3d;
    class IExternalObject;

    /// 普通对象接口类
    /// 
    /// 外部对象通过IGenericElement类适配就可当成Element处理
    class GCMP_MODEL_INTERFACE_EXPORT IGenericElement : public IElement
    {
        DEFINE_CAST_DERIVED(gcmp::IGenericElement, gcmp::IElement);
    public:
        
        /// \brief 创建通用的对象
        /// 
        /// 用途：当外部创建外部对象时，应将外部对象加入平台的通用对象中，则平台即可将外部对象当成Element处理。
        /// \param pDocument 当前文档
        /// \param opExternalObject 外部对象
        /// \param externalClassificationGuid 外部对象分类Guid
        /// \param elementCreationOption 元素创建选项
        /// \param moduleGroupGuid 模块组Guid。当externalObject中含有自定义格式数据、并且希望将IGenericElement归属未进行定制的模块组时，提供模块组Guid。
        /// \param bCreateGeometryRelationshipComponent 是否创建默认几何关系组件
        /// \return 通用对象指针
        /// \see IElementBehaviorsManager
        static IGenericElement* Create(
            IDocument* pDocument,
            OwnerPtr<IExternalObject> opExternalObject,
            Guid externalClassificationGuid,
            ElementCreationOptions elementCreationOption = ElementCreationOptions::Normal,
            const Guid & moduleGroupGuid = GuidUtils::GetInvalid(),
            bool bCreateGeometryRelationshipComponent = true
        );

        /// \brief 创建通用的对象
        /// 
        /// 用途：当外部创建外部对象时，应将外部对象加入平台的通用对象中，则平台即可将外部对象当成Element处理。
        /// \param pDocument 当前文档
        /// \param opExternalObject 外部对象
        /// \param externalClassificationGuid 外部对象分类Guid
        /// \param categoryUid 外部对象类型ID
        /// \param elementCreationOption 元素创建选项
        /// \param moduleGroupGuid 模块组Guid。当externalObject中含有自定义格式数据、并且希望将IGenericElement归属未进行定制的模块组时，提供模块组Guid。
        /// \param bCreateGeometryRelationshipComponent 是否创建默认几何关系组件
        /// \return 通用对象指针
        /// \see IElementBehaviorsManager
        static IGenericElement* Create(
            IDocument* pDocument,
            OwnerPtr<IExternalObject> opExternalObject,
            Guid externalClassificationGuid,
            UniIdentity categoryUid,
            ElementCreationOptions elementCreationOption = ElementCreationOptions::Normal,
            const Guid & moduleGroupGuid = GuidUtils::GetInvalid(),
            bool bCreateGeometryRelationshipComponent = true
        );

        /// \brief 获得外部对象
        /// \return 外部对象指针
        virtual const IExternalObject* GetExternalObject() const = 0;

        /// \brief 获得外部对象
        /// \return 外部对象指针
        virtual IExternalObject* GetExternalObject() = 0;

        /// \brief 设置Element刪除组件接口
        /// \param opElementDeletionComponent 要设置的Element刪除组件
        /// \return 设置成功返回true，否则返回false
        /// \see IElementDeletionComponent
        virtual bool SetElementDeletionComponent(OwnerPtr<IElementDeletionComponent> opElementDeletionComponent) = 0;


        /// \brief 设置位置报告组件
        /// \param opElementPositionReportComponent 位置报告组件
        /// \return bool
        virtual bool SetElementPositionReportComponent(OwnerPtr<IElementPositionReportComponent> opElementPositionReportComponent) = 0;

        /// \brief 设置几何关系组件(如连接、打断、扣减等关系)
        /// \param opGeometrtyRelationshipComponent 几何关系组件
        virtual void SetGeometryRelationshipComponent(OwnerPtr<IGeometryRelationshipComponent> opGeometrtyRelationshipComponent) = 0;

        /// \brief 设置造型操作接口
        /// \param opElementModelingOperations 造型操作
        virtual void SetElementModelingOperations(OwnerPtr<IElementModelingOperations> opElementModelingOperations) = 0;

    public:
        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();
    };

}// namespace gcmp


